# 游戏包
import pygame
from pygame.locals import *
# 时间包
import time
import os
import random

'''
API:
# 创建游戏窗口
window = pygame.display.set_mode((512,536),0,0)
# 创建游戏背景
backgroud = pygame.image.load（文件路径）
# 设置游戏背景以及位置
window.blit(backgroud,(x,bg_y))
# 刷新显示游戏背景
pygame.display.update()
'''
# 默认全局变量
file_path = os.getcwd() + os.sep
# 窗口宽高
w_weight = 512
w_height = 536
# 玩家飞机 宽高
p_weight = 106
p_height = 76
# 敌人飞机 宽高
e_weight = 98
e_height = 76
# 玩家飞机移动速度
p_speed = 4
# 子弹移动速度
b_speed = 10

class BasePlane():
    ''' 飞机类 '''
    def __init__(self,window):
        self.x = 0
        self.y = 0
        self.image = None
        self.window = window
        self.max_x = w_weight - p_weight
        self.bullet_list = []

    def disPlay(self):
        self.window.blit(self.image,(self.x,self.y))

    def player_move(self,x,y):
        self.x += x
        self.y += y
        # 边界判断
        if self.x <= 0:
            self.x = 0
        if self.x >= self.max_x:
            self.x = self.max_x

        if self.y <= 0:
            self.y = 0
        if self.y >= w_height - p_height:
            self.y = w_height - p_height




class Player(BasePlane):
    ''' 玩家类 '''
    def __init__(self,window,enemy_list):
        super().__init__(window)
        self.x = w_weight/2 - p_weight/2
        self.y = w_height - p_height
        self.image = pygame.image.load(file_path+'images/me.png')
        self.enemy_list = enemy_list
        self.is_clear = False

    def disPlay(self):
        super().disPlay()
        # 遍历子弹列表 绘制 移动子弹
        for b in self.bullet_list:
            b.disPlay()
            if b.pd_move(-b_speed):
                self.bullet_list.remove(b)

    def player_move(self,x,y):
        super().player_move(x,y)

    def clear(self):
         self.is_clear = True

    def is_rect_intersect(self,l,t,r,b,l1,t1,r1,b1):
        # 判断俩个矩形是否相交  参数分别为 左上右下  俩个矩形
        # 中心点相对于矩形位置
        rect_centre_x = (r - l) / 2
        rect_centre_y = abs((b - t) / 2)
        rect1_centre_x = (r1 - l1) / 2
        rect1_centre_y = abs((b1 - t1) / 2)
        # 中心点相对于屏幕位置
        radius_x = r - rect_centre_x
        radius_y = b - rect_centre_y
        radius1_x = r1 - rect1_centre_x
        radius1_y = b1 - rect1_centre_y

        # -20 缩小碰撞区域
        if(abs(radius_x - radius1_x) < abs(rect_centre_x + rect1_centre_x) - 20 and abs(radius_y - radius1_y) < abs(rect_centre_y + rect1_centre_y) - 20):
            return True


    def collision(self):
        ''' 用于进行碰撞检测 '''
        for enemy in self.enemy_list:
           if self.is_rect_intersect(self.x,self.y,self.x + p_weight,self.y + p_height,enemy.x,enemy.y,enemy.x+e_weight,enemy.y+e_height):
                print("发生碰撞")
                return True
           for bo in enemy.bullet_list:
                if(bo.x > self.x + 10 and bo.x < self.x + p_weight -10 and bo.y > self.y + 10 and bo.y < self.y + p_height - 10):
                    enemy.bullet_list.remove(bo)
                    return True

    def fs(self):
        ''' 子弹发射方法 '''
        # 将子弹添加到子弹列表
        self.bullet_list.append(Bullet(self.x + p_weight / 2,self.y,self.window))

class Bullet():
    ''' 子弹类 '''
    def __init__(self,x,y,window):
        # self.x = player.x + p_weight / 2
        # self.y = player.y
        self.x = x
        self.y = y
        self.image = pygame.image.load(file_path+'images/pd.png')
        self.window = window

    def disPlay(self):
        self.window.blit(self.image,(self.x,self.y))

    def pd_move(self,speed):
        self.y += speed
        # 判断子弹出界
        if(self.y <= 0 or self.y >= w_height):
            return True


class Enemy(BasePlane):
    ''' 敌人类 '''
    def __init__(self,window):
        super().__init__(window)
        self.x = random.choice(range(w_weight - e_weight))
        self.y = -1 - e_height
        self.image = pygame.image.load(file_path+'images/e1.png')

    def disPlay(self):
        super().disPlay()
        if random.choice(range(20)) == 5:
           self.bullet_list.append(Bullet(self.x + e_weight / 2,self.y + p_height,self.window))

        for b in self.bullet_list:
            b.disPlay()
            if b.pd_move(b_speed):
                self.bullet_list.remove(b)

    def e_move(self,player):
        self.y += p_speed
        # 判断敌人出界
        if self.y >= w_height:
            return True
        for bo in player.bullet_list:
            if(bo.x > self.x + 10 and bo.x < self.x + p_weight -10 and bo.y > self.y + 10 and bo.y < self.y + p_height - 10):
                player.bullet_list.remove(bo)
                return True

class Burst():
    ''' 爆炸效果类 '''
    def __init__(self,window):
        self.window = window
        self.burst = [pygame.image.load(file_path+'images/bomb1.png')
            ,pygame.image.load(file_path+'images/bomb2.png')
            ,pygame.image.load(file_path+'images/bomb3.png')
            ,pygame.image.load(file_path+'images/bomb4.png')]

    def disPlay(self,x,y):
        for image in self.burst:
            self.window.blit(image,(x,y))

def key_control(player):

    ''' 程序键盘控制 '''
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()

    if(player.is_clear):
        return

    # 获取所有按键信息
    keys = pygame.key.get_pressed()
    # 按下左方向 或者 a
    if(keys[K_LEFT] or keys[K_a]):
        player.player_move(-p_speed,0)
        print("lift")
    # 按下右方向 或者 b
    elif(keys[K_RIGHT] or keys[K_d]):
        player.player_move(p_speed,0)
        print("right")

        # 按下左方向 或者 a
    if(keys[K_UP] or keys[K_w]):
        player.player_move(0,-p_speed)
        print("lift")
    # 按下右方向 或者 b
    elif(keys[K_DOWN] or keys[K_s]):
        player.player_move(0,p_speed)
        print("right")

    # 按下空格
    if(keys[K_SPACE]):
        player.fs()
        print("空格")
        print(len(player.bullet_list))


def main():
    ''' 程序主进程 或者理解为程序入口 '''
    pygame.init()
    # 设置游戏窗口
    window = pygame.display.set_mode((w_weight,w_height),0,0)
    # 绘制白色结束文本
    fontObj =  pygame.font.SysFont('arial', 50)
    textSurface = fontObj.render("GAME  OVER",True,(255,255,255))
    # 获得游戏背景
    backgroud = pygame.image.load(file_path+'images/bg2.jpg')
    # 定义游戏背景 Y 轴初始坐标  bg_y = 背景图高度 - 游戏窗口高度
    bg_y = -1000
    # 初始化敌人集合
    enemy_list = []
    # 初始化玩家
    player = Player(window,enemy_list)
    # 爆炸效果
    burst = Burst(window)
    while True:
        # 绘制游戏背景以及位置
        window.blit(backgroud,(0,bg_y))
        # 每次向下移动 5 个像素点
        bg_y += 2
        # 判断背景越界  当 bg_y == -1000 + 1536 / 2 时 背景与窗口为完全契合 重置背景
        if bg_y >= -232:
            bg_y = -1000
        # 循环休眠  每0.04秒刷新一次  每秒 24 次刷新即可保持流畅  6 / 24
        time.sleep(0.04)
        if(player.is_clear):
            window.blit(textSurface,(100,w_height - 200))
        else:
            # 绘制玩家
            player.disPlay()
            # 绘制敌机
            if(random.choice(range(50)) == 10):
                enemy_list.append(Enemy(window))
            # 绘制敌人 维护移动
            for e in enemy_list:
                e.disPlay()
                if(e.e_move(player)):
                    # 显示爆炸效果
                    burst.disPlay(e.x,e.y)
                    enemy_list.remove(e)

            # 检测玩家与子弹碰撞
            if(player.collision()):
                burst.disPlay(player.x,player.y)
                player.clear()

        # 更新游戏窗口视图
        pygame.display.update()
        # 键盘输入监听
        key_control(player)

if __name__ == '__main__':
    main()